package hackathon1212;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class ServletPojoAdapter extends HttpServlet {

	/**
	 * 	This method should be used to code the query logic (if any), typically this 
	 * 	should return a single item, or collection of results. If there are any 
	 * 	pre-reqs to calling this query then those should be documented.
	 * 
	 *  OR you can put all you logic in this method, and then decide which
	 *  CRUD operation you are going to do based on the params that are passed in.
	 *  In this case you should not override any of the other methods (as they will 
	 *  just pass though to this anyway)
	 * 
	 * 	The return value can be a Data Transfer Object, Map, List or a single value.
	 * 
	 * @param params the parameters that the caller has supplied
	 * 			You should define in your documentation for the API the expected
	 * 			parameters and format.
	 * 
	 * @return Here you may return a single or collection of results.
	 * 			You should define in your documentation for the API the expected
	 * 			responses.
	 */
	protected Object getBusinessMethod(Map<String, String[]> params){
		return null;
	}
	
	/**
	 * 	This method should be used to code the update(if any), 
	 *  typically might take in a set of params and process them. Attempts to make the 
	 *  calling code simpler are appreciated. e.g. Simple flattened 
	 *  data structures are preferred.
	 *  
	 *  If there are any pre-reqs to calling this query then those should be 
	 *  documented.
	 * 
	 * @param params the parameters that the caller has supplied
	 * 			You should define in your documentation for the API the expected
	 * 			parameters and format.
	 * 
	 * @return Here you may return enough information to the caller to detemine the 
	 * 			status of the request e.g. {"status" : "success"} or 
	 * 			{"status" : "failed", "message" : "invalid card number"}
	 */
	protected Object postBusinessMethod(Map<String, String[]> params){
		return getBusinessMethod(params);
	}
	
	/**
	 * 	This method should be used to code the creation logic (if any), 
	 *  typically might take in a set of params and process them. Attempts to make the 
	 *  calling code simpler are appreciated. e.g. Simple flattened 
	 *  data structures are preferred.
	 *  
	 *  If there are any pre-reqs to calling this query then those should be 
	 *  documented.
	 * 
	 * @param params the parameters that the caller has supplied
	 * 			You should define in your documentation for the API the expected
	 * 			parameters and format.
	 * 
	 * @return Here you may return enough information to the caller to detemine the 
	 * 			status of the request e.g. {"status" : "success"} or 
	 * 			{"status" : "failed", "message" : "invalid card number"}
	 */
	protected Object putBusinessMethod(Map<String, String[]> params){
		return getBusinessMethod(params);
	}
	
	/**
	 * 	This method should be used to code the deletion logic (if any), 
	 *  typically might take in a set of params and process them. Attempts to make the 
	 *  calling code simpler are appreciated. e.g. Simple flattened 
	 *  data structures are preferred.
	 *  
	 *  If there are any pre-reqs to calling this query then those should be 
	 *  documented.
	 * 
	 * @param params the parameters that the caller has supplied
	 * 			You should define in your documentation for the API the expected
	 * 			parameters and format.
	 * 
	 * @return Here you may return enough information to the caller to detemine the 
	 * 			status of the request e.g. {"status" : "success"} or 
	 * 			{"status" : "failed", "message" : "invalid card number"}
	 */
	protected Object deleteBusinessMethod(Map<String, String[]> params){
		return getBusinessMethod(params);
	}
		
	private static final long serialVersionUID = -5580756574768315754L;

	@Override
	protected final void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		
		@SuppressWarnings("unchecked")
		final Object result = this.getBusinessMethod(request.getParameterMap());
		
		reply(request, response, result);
	}
	
	@Override
	protected final void doPut(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		
		@SuppressWarnings("unchecked")
		final Object result = this.putBusinessMethod(request.getParameterMap());
		
		reply(request, response, result);
	}
	
	@Override
	protected final void doDelete(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		
		@SuppressWarnings("unchecked")
		final Object result = this.deleteBusinessMethod(request.getParameterMap());
		
		reply(request, response, result);
	}
	
	@Override
	protected final void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {		
		@SuppressWarnings("unchecked")
		final Object result = this.postBusinessMethod(request.getParameterMap());		
		reply(request, response, result);
	}

	private void reply(HttpServletRequest request,
			HttpServletResponse response, final Object result)
			throws IOException {
		final String jsonp = request.getParameter("jsonp");
		final String prefix = (jsonp!=null && jsonp!="") ? jsonp + "(" : "";
		final String suffix = (jsonp!=null && jsonp!="") ? ")" : "";
		response.setCharacterEncoding("UTF-8");
		response.getWriter().write(prefix  + GsonFactory.get().toJson(result) + suffix);
		response.getWriter().flush();
		response.getWriter().close();
	}

}
